package com.blog.cmrpersonalblog.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.blog.cmrpersonalblog.common.Result;
import com.blog.cmrpersonalblog.dto.announcement.request.AnnouncementBatchOperationRequest;
import com.blog.cmrpersonalblog.dto.announcement.request.AnnouncementCreateRequest;
import com.blog.cmrpersonalblog.dto.announcement.request.AnnouncementQueryRequest;
import com.blog.cmrpersonalblog.dto.announcement.request.AnnouncementUpdateRequest;
import com.blog.cmrpersonalblog.dto.announcement.response.AnnouncementResponse;
import com.blog.cmrpersonalblog.service.AnnouncementService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * 管理端公告控制器
 * 提供公告的管理功能，包括发布、查询、更新、删除、存档等
 */
@Slf4j
@RestController
@RequestMapping("/admin/announcements")
@CrossOrigin(origins = "*", maxAge = 3600)
@SaCheckRole("admin")
@Validated
public class AdminAnnouncementController {

   @Resource
    private AnnouncementService announcementService;

    /**
     * 分页查询公告列表（管理员）
     */
    @GetMapping("/list")
    public Result<IPage<AnnouncementResponse>> getAnnouncementList(AnnouncementQueryRequest queryRequest) {
        log.info("管理员查询公告列表: {}", queryRequest);
        try {
            IPage<AnnouncementResponse> pageResult = announcementService.getAnnouncementList(queryRequest);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("查询公告列表失败", e);
            return Result.error("查询公告列表失败：" + e.getMessage());
        }
    }

    /**
     * 创建公告
     */
    @PostMapping("/create")
    public Result<Void> createAnnouncement(@RequestBody @Valid AnnouncementCreateRequest createRequest) {
        Long creatorId = StpUtil.getLoginIdAsLong();
        String creatorName = StpUtil.getLoginIdAsString();
        log.info("管理员创建公告: request={}, creatorId={}", createRequest, creatorId);
        
        try {
            boolean success = announcementService.createAnnouncement(createRequest, creatorId, creatorName);
            if (success) {
                return Result.success("公告创建成功");
            } else {
                return Result.error("公告创建失败");
            }
        } catch (Exception e) {
            log.error("创建公告失败", e);
            return Result.error("创建公告失败：" + e.getMessage());
        }
    }

    /**
     * 更新公告
     */
    @PutMapping("/{announcementId}")
    public Result<Void> updateAnnouncement(@PathVariable @NotNull Long announcementId,
                                          @RequestBody @Valid AnnouncementUpdateRequest updateRequest) {
        Long updaterId = StpUtil.getLoginIdAsLong();
        String updaterName = StpUtil.getLoginIdAsString();
        log.info("管理员更新公告: id={}, request={}, updaterId={}", announcementId, updateRequest, updaterId);
        
        try {
            // 设置公告ID和更新人信息
            updateRequest.setId(announcementId);
            updateRequest.setUpdaterId(updaterId);
            updateRequest.setUpdaterName(updaterName);
            
            boolean success = announcementService.updateAnnouncement(updateRequest);
            if (success) {
                return Result.success("公告更新成功");
            } else {
                return Result.error("公告更新失败");
            }
        } catch (Exception e) {
            log.error("更新公告失败", e);
            return Result.error("更新公告失败：" + e.getMessage());
        }
    }

    /**
     * 删除公告
     */
    @DeleteMapping("/{announcementId}")
    public Result<Void> deleteAnnouncement(@PathVariable @NotNull Long announcementId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        String operatorName = StpUtil.getLoginIdAsString();
        log.info("管理员删除公告: id={}, operatorId={}", announcementId, operatorId);
        
        try {
            boolean success = announcementService.deleteAnnouncement(announcementId, operatorId, operatorName);
            if (success) {
                return Result.success("公告删除成功");
            } else {
                return Result.error("公告删除失败");
            }
        } catch (Exception e) {
            log.error("删除公告失败", e);
            return Result.error("删除公告失败：" + e.getMessage());
        }
    }

    /**
     * 批量操作公告
     */
    @PostMapping("/batch")
    public Result<Map<String, Object>> batchOperateAnnouncements(@RequestBody @Valid AnnouncementBatchOperationRequest batchRequest) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        String operatorName = StpUtil.getLoginIdAsString();
        log.info("管理员批量操作公告: request={}, operatorId={}", batchRequest, operatorId);

        try {
            // 设置操作人信息
            batchRequest.setOperatorId(operatorId);
            batchRequest.setOperatorName(operatorName);

            Map<String, Object> result = announcementService.batchOperateAnnouncements(batchRequest);
            return Result.success("批量操作完成", result);
        } catch (Exception e) {
            log.error("批量操作公告失败", e);
            return Result.error("批量操作失败：" + e.getMessage());
        }
    }

    /**
     * 发布公告
     */
    @PostMapping("/{announcementId}/publish")
    public Result<Void> publishAnnouncement(@PathVariable @NotNull Long announcementId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        String operatorName = StpUtil.getLoginIdAsString();
        log.info("管理员发布公告: id={}, operatorId={}", announcementId, operatorId);

        try {
            boolean success = announcementService.publishAnnouncement(announcementId, operatorId, operatorName);
            if (success) {
                return Result.success("公告发布成功");
            } else {
                return Result.error("公告发布失败");
            }
        } catch (Exception e) {
            log.error("发布公告失败", e);
            return Result.error("发布公告失败：" + e.getMessage());
        }
    }

    /**
     * 存档公告
     */
    @PostMapping("/{announcementId}/archive")
    public Result<Void> archiveAnnouncement(@PathVariable @NotNull Long announcementId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        String operatorName = StpUtil.getLoginIdAsString();
        log.info("管理员存档公告: id={}, operatorId={}", announcementId, operatorId);

        try {
            boolean success = announcementService.archiveAnnouncement(announcementId, operatorId, operatorName);
            if (success) {
                return Result.success("公告存档成功");
            } else {
                return Result.error("公告存档失败");
            }
        } catch (Exception e) {
            log.error("存档公告失败", e);
            return Result.error("存档公告失败：" + e.getMessage());
        }
    }

    /**
     * 置顶/取消置顶公告
     */
    @PostMapping("/{announcementId}/top")
    public Result<Void> toggleAnnouncementTop(@PathVariable @NotNull Long announcementId,
                                             @RequestParam boolean isTop) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        String operatorName = StpUtil.getLoginIdAsString();
        log.info("管理员切换公告置顶状态: id={}, isTop={}, operatorId={}", announcementId, isTop, operatorId);

        try {
            boolean success = announcementService.toggleAnnouncementTop(announcementId, isTop, operatorId, operatorName);
            if (success) {
                String operation = isTop ? "置顶" : "取消置顶";
                return Result.success("公告" + operation + "成功");
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("切换公告置顶状态失败", e);
            return Result.error("操作失败：" + e.getMessage());
        }
    }

    /**
     * 设置/取消弹窗公告
     */
    @PostMapping("/{announcementId}/popup")
    public Result<Void> toggleAnnouncementPopup(@PathVariable @NotNull Long announcementId,
                                               @RequestParam boolean isPopup) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        String operatorName = StpUtil.getLoginIdAsString();
        log.info("管理员切换公告弹窗状态: id={}, isPopup={}, operatorId={}", announcementId, isPopup, operatorId);

        try {
            boolean success = announcementService.toggleAnnouncementPopup(announcementId, isPopup, operatorId, operatorName);
            if (success) {
                String operation = isPopup ? "设为弹窗" : "取消弹窗";
                return Result.success("公告" + operation + "成功");
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("切换公告弹窗状态失败", e);
            return Result.error("操作失败：" + e.getMessage());
        }
    }

    /**
     * 获取公告统计信息
     */
    @GetMapping("/statistics")
    public Result<Map<String, Object>> getAnnouncementStatistics() {
        log.info("管理员获取公告统计信息");
        try {
            Map<String, Object> statistics = announcementService.getAnnouncementStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取公告统计信息失败", e);
            return Result.error("获取统计信息失败：" + e.getMessage());
        }
    }

    /**
     * 自动过期公告
     */
    @PostMapping("/auto-expire")
    public Result<Integer> autoExpireAnnouncements() {
        log.info("管理员执行自动过期公告");
        try {
            int count = announcementService.autoExpireAnnouncements();
            return Result.success("自动过期完成", count);
        } catch (Exception e) {
            log.error("自动过期公告失败", e);
            return Result.error("自动过期失败：" + e.getMessage());
        }
    }

    /**
     * 清理已删除的公告
     */
    @PostMapping("/clean-deleted")
    public Result<Integer> cleanDeletedAnnouncements(@RequestParam(defaultValue = "30") int daysBeforeClean) {
        log.info("管理员清理已删除公告: daysBeforeClean={}", daysBeforeClean);
        try {
            int count = announcementService.cleanDeletedAnnouncements(daysBeforeClean);
            return Result.success("清理完成", count);
        } catch (Exception e) {
            log.error("清理已删除公告失败", e);
            return Result.error("清理失败：" + e.getMessage());
        }
    }

    /**
     * 清理过期的阅读记录
     */
    @PostMapping("/clean-read-records")
    public Result<Integer> cleanExpiredReadRecords(@RequestParam(defaultValue = "90") int daysBeforeClean) {
        log.info("管理员清理过期阅读记录: daysBeforeClean={}", daysBeforeClean);
        try {
            int count = announcementService.cleanExpiredReadRecords(daysBeforeClean);
            return Result.success("清理完成", count);
        } catch (Exception e) {
            log.error("清理过期阅读记录失败", e);
            return Result.error("清理失败：" + e.getMessage());
        }
    }
}
